#include "ConfigFile.h"
#include <fstream>
#include <stdio.h>

ConfigFile::ConfigFile(std::string path){
	
    std::ifstream source(path.c_str());
    if (!source.is_open()){
        fprintf(stderr,"Could not open ConfigFile %s\n",path.c_str());
    }

    char buf[255];
    std::string line;
    std::string currentSection = "__undefined";
    while(!source.eof()){
        source.getline(buf,255);
        // on enleve les commentaires de façon un peu brutale,
        // et on en profite pour voir si il s'agit d'une section
        bool leftBracket=false,rightBracket=false,equalSign=false;
        bool inString=false;
        short endPos=255;
        for (int i=0;i<255;i++){
            if (buf[i]=='"' || buf[i]=='\'')//to fix!!! '!="
                inString=!inString;
            if (inString)	{continue;}

            if (buf[i]==';'){buf[i]=0;}
            if (buf[i]=='\r'){buf[i]=0;}
            if (buf[i]==0)	{endPos=i;break;}
            if (buf[i]=='['){leftBracket=true;}
            if (buf[i]==']'){rightBracket=true;}
            if (buf[i]=='='){equalSign=true;}
        }

        line = buf;
        if (endPos==0){continue;}

        // on a trouvé une section
        if (leftBracket && rightBracket){
            int i=line.find('[')+1,j=line.find(']');
            currentSection = line.substr(i,j-i);
        }
        else if (equalSign){
            int i=line.find('=');
            std::string param = line.substr(0,i);
            std::string value = line.substr(i+1);
            boost::trim(param);boost::trim(value);
            m_data[currentSection](param)=value;
            //boost::trim
        }
        else if (line.size()==0){
            continue;
        }
        else{
            fprintf(stderr,"ConfigFile::ConfigFile(): Invalid line: \"%s\"\n",line.c_str());
        }
    }
}

Math::Vector ConfigFileAttrib::asVector(){
    float x,y,z=0;
    if (sscanf(m_string.c_str(),"%f,%f,%f",&x,&y,&z)<3){
        if (sscanf(m_string.c_str(),"%f,%f",&x,&y)<2){
            fprintf(stderr,"ConfigFileAttrib::asVector(): Error parsing %s\n",m_string.c_str());
        }
    }
    return Math::Vector(x,y,z);
}

std::string ConfigFileAttrib::asString(){
    return m_string;
}

float ConfigFileAttrib::asFloat(){
    float x = 0;
    if (sscanf(m_string.c_str(),"%f",&x)<1){
        fprintf(stderr,"ConfigFileAttrib::asFloat(): Error parsing %s\n",m_string.c_str());
    }
    return x;
}

int ConfigFileAttrib::asInt(){
    int x = 0;
    if (sscanf(m_string.c_str(),"%d",&x)<1){
        fprintf(stderr,"ConfigFileAttrib::asInt(): Error parsing %s\n",m_string.c_str());
    }
    return x;
}

std::vector<std::string> ConfigFileAttrib::asStringVector(){
    std::vector<std::string> v;
    std::string s = m_string;
    std::string temp;
    while (s.size()){
        size_t it = s.find(",");
        if (it!=std::string::npos){
            temp = s.substr(0,it);
            boost::trim(temp);
            v.push_back(temp);
            s = s.substr(++it);
        }
        else{ // plus de virgules a séparer
            boost::trim(s);
            v.push_back(s);
            break;
        }
    }
    return v;
}

Material ConfigFileAttrib::asMaterial(){
    
    //R,G,B,Diffuse,Reflect,Specular,Diffraction
    float x,y,z,w,u,v,n=-1.0f;
    if (sscanf(m_string.c_str(),"%f,%f,%f,%f,%f,%f",&x,&y,&z,&w,&u,&v)<6)
        if (sscanf(m_string.c_str(),"%f,%f,%f,%f,%f,%f,%f",&x,&y,&z,&w,&u,&v,&n)<7)
            fprintf(stderr,"ConfigFileAttrib::asMaterial(): Error parsing %s\n",m_string.c_str());
    return Material(Pixelf(x,y,z),w,u,v,n);
}
